package one.stand.controller;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.TemplateApi;
import com.jmp.base.dto.GoodsMainPushRequest;
import com.jmp.base.dto.*;
import com.jmp.feign.AccountFeign;
import com.jmp.feign.GoodsFeign;
import com.jmp.feign.GoodsTypeFeign;
import com.jmp.feign.TemplateFeign;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import one.stand.advice.ResultEnum;
import com.jmp.api.dto.GoodsSaveRequest;
import com.jmp.api.dto.*;
import one.stand.dto.ConvertUtils;
import one.stand.dto.PageResponse2;
import one.stand.enums.LoginEnum;
import one.stand.mapper.GoodSpecMapperExt;
import one.stand.mapper.GoodsApiCrmMapper;
import one.stand.model.*;
import one.stand.request.GoodSpecRequest;
import one.stand.request.GoodsRequest;
import one.stand.service.CompanyBaseService;
import one.stand.service.GoodsBaseService;
import one.stand.service.GoodsPhotoService;
import one.stand.service.GoodsTypeService;
import one.stand.util.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 产品信息管理
 *
 * @author Administrator
 */
@RestController
@RequestMapping("crmApi/goods")
public class GoodsController extends BaseController {
    @Autowired
    private TemplateFeign templateFeign;
    @Autowired
    private GoodsFeign goodsFeign;
    @Autowired
    private AccountFeign accountFeign;

    @Autowired
    private GoodsTypeFeign goodsTypeFeign;
    @Autowired
    private GoodsTypeService goodsTypeService;
    @Autowired
    private CompanyBaseService companyBaseService;
    @Autowired
    private GoodsApiCrmMapper goodsApiCrmMapper;
    @Autowired
    private GoodsPhotoService goodsPhotoService;
    @Autowired
    private GoodsBaseService goodsBaseService;
    @Autowired
    private GoodSpecMapperExt goodSpecMapperExt;

    @ApiOperation(value = "首页")
    @PostMapping("/index")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsIndexResponse> index(@RequestAttribute GoodsIndexRequest request) {
        String stime = null;
        String etime = null;
        Date now = new Date();
        if (request.getType() == 1) {
            stime = DateUtil.format.format(DateUtil.getBeforeOrAfterDate(now, -1));
            etime = DateUtil.format.format(now);
        } else if (request.getType() == 2) {
            stime = DateUtil.format.format(DateUtil.getBeforeOrAfterDate(now, -6));
        } else if (request.getType() == 3) {
            stime = DateUtil.format.format(DateUtil.getBeforeOrAfterDate(now, -29));
        }
        Integer totalCount = goodsApiCrmMapper.selectGoodsViewCount(request.getCId(), null, stime, etime);
        Integer myCount = goodsApiCrmMapper.selectGoodsViewCount(request.getCId(), request.getMyCardId(), stime, etime);
        Integer cardNum = goodsApiCrmMapper.selectCardNum(request.getCId());
        Integer averageCount = cardNum > 0 ? totalCount / cardNum : 0;
        String memo;
        if (myCount > averageCount) {
            memo = "太棒了，你的访问浏览数超过平均水平，继续保持!";
        } else if (myCount == averageCount) {
            memo = "你的数据已达到平均水平，继续加油！";
        } else {
            memo = "很遗憾，您的数据还未达到平均水平，还需要再努力！";
        }
        GoodsIndexResponse response = GoodsIndexResponse.builder()
                .myCount(myCount)
                .averageCount(averageCount)
                .totalCount(totalCount)
                .memo(memo)
                .build();
        return ResultModel.success(response);
    }

    @PostMapping("/updateSelectGoods")
    @ApiOperation(value = "修改优选产品")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<Integer> updateSelectGoods(@RequestAttribute GoodsSelectRequest request) {
        GoodsPriceRemarkRequest goodsPriceRemarkRequest = GoodsPriceRemarkRequest.builder()
                .goodsId(request.getGoodsId())
                .showPrice(request.getShowPrice())
                .isPayment(null)
                .specs(ConvertUtils.list(request.getSpecs(), spec -> GoodsPriceRemarkRequest.GoodsSpec.builder()
                        .specId(spec.getSpecId())
                        .priceRemark(spec.getPriceRemark())
                        .build()))
                .build();
        goodsFeign.priceRemark(goodsPriceRemarkRequest);
        return ResultModel.success();
    }

    @ApiOperation(value = "修改优选产品显示状态")
    @PostMapping("/updateSelectShowState")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<Integer> updateSelectShowState(@RequestAttribute GoodsRequest request) {
        Integer isShow = request.getIsShow();
        if (isShow == 0) {
            goodsFeign.show(GoodsShowRequest.builder().id(request.getGoodsId()).build());
        } else {
            goodsFeign.hide(GoodsHideRequest.builder().id(request.getGoodsId()).build());
        }
        return ResultModel.success();
    }

    @ApiOperation(value = "商品列表/优选商品列表")
    @ApiImplicitParams({})
    @PostMapping("/getGoodsTypeInfo")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<PageResponse2<GoodsListResponse>> getGoodsTypeInfo(@RequestAttribute GoodsTypeListRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        String nameLike = SqlUtil.like(request.getKeyword());
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<Goods> goodsModelList = goodsApiCrmMapper.selectGoodsInfo(
                request.getParentId()
                , request.getCId()
                , request.getIsSelect()
                , request.getTabType()
                , nameLike
        );

        Company company = companyBaseService.getById(optUser.getCompanyId());
        Integer userId = company.getUserId();

        PageResponse2<GoodsListResponse> response = ConvertUtils.page2(goodsModelList, goodsModel -> {
            GoodsType goodsType = goodsTypeService.get(goodsModel.getGoodstypeId());
            return GoodsListResponse.builder()
                    .goodsId(goodsModel.getGoodsId())
                    .goodsName(goodsModel.getGoodsName())
                    .goodstypeId(goodsModel.getGoodstypeId())
                    .companyId(goodsModel.getCompanyId())
                    .goodsDetails(goodsModel.getGoodsDetails())
                    .isPayment(goodsModel.getIsPayment())
                    .remark(goodsModel.getRemark())
                    .coverImg(goodsModel.getCoverImg())
                    .qjWholesalePrice(Objects.nonNull(goodsModel.getQjWholesalePrice()) ? BigDecimal.valueOf(goodsModel.getQjWholesalePrice()) : null)
                    .qjVrUrl(goodsModel.getQjVrUrl())
                    .videoUrl(goodsModel.getVideoUrl())
                    .isShow(goodsModel.getIsShow())
                    .showPrice(goodsModel.getShowPrice())
                    .price(MoneyUtil.getMoneyInt(goodsModel.getPrice()))
                    .contactInfo(goodsModel.getContactInfo())
                    .mainPush(goodsModel.getMainPush())
                    .userId(userId)
                    .goodPhoto(goodsPhotoService.getPath(goodsModel.getGoodsId()))
                    .groupName(Objects.nonNull(goodsType) ? goodsType.getGroupName() : null)
                    .build();
        });

        return ResultModel.success(response);
    }

    @ApiOperation(value = "隐藏分类列表")
    @PostMapping("/type/parent")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsTypeParentResponse> getGoodsTypeParent(@RequestAttribute GoodsTypeParentRequest request) {
        // 获取一级分类
        Integer parentId = Objects.nonNull(request.getParentId()) ? request.getParentId() : GoodsTypeService.PARENT_ID;
        List<GoodsType> list = goodsApiCrmMapper.selectTypesChild(parentId, request.getCId(), request.getIsSelect(), false);
        List<GoodsTypeParentResponse.Type> types = ConvertUtils.list(list, type -> GoodsTypeParentResponse.Type.builder()
                .id(type.getGoodstypeId())
                .name(type.getGroupName())
                .isShow(type.getIsShow())
                .build());

        // 填充二级分类
        for (GoodsTypeParentResponse.Type type : types) {
            List<GoodsType> children = goodsApiCrmMapper.selectTypesChild(type.getId(), request.getCId(), request.getIsSelect(), false);
            type.setChildren(ConvertUtils.list(children, child -> GoodsTypeParentResponse.Type.builder()
                    .id(child.getGoodstypeId())
                    .name(child.getName())
                    .isShow(child.getIsShow())
                    .build()));
        }
        GoodsTypeParentResponse response = GoodsTypeParentResponse.builder()
                .types(types)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "产品管理-分类列表")
    @PostMapping("/type/list")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsTypeParentResponse> typeList(@RequestAttribute GoodsTypeParentRequest request) {
        // 获取一级分类
        Integer parentId = Objects.nonNull(request.getParentId()) ? request.getParentId() : GoodsTypeService.PARENT_ID;
        List<GoodsType> list = goodsApiCrmMapper.selectTypesChild(parentId, request.getCId(), request.getIsSelect(), true);
        List<GoodsTypeParentResponse.Type> types = ConvertUtils.list(list, type -> GoodsTypeParentResponse.Type.builder()
                .id(type.getGoodstypeId())
                .name(type.getGroupName())
                .build());

        // 填充二级分类
        for (GoodsTypeParentResponse.Type type : types) {
            List<GoodsType> children = goodsApiCrmMapper.selectTypesChild(type.getId(), request.getCId(), request.getIsSelect(), true);
            type.setChildren(ConvertUtils.list(children, child -> GoodsTypeParentResponse.Type.builder()
                    .id(child.getGoodstypeId())
                    .name(child.getName())
                    .build()));
        }
        GoodsTypeParentResponse response = GoodsTypeParentResponse.builder()
                .types(types)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "查询所有二级分类（用于商品分类下拉列表）")
    @PostMapping("/type/child")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<List<GoodsTypeSelectResponse>> getGoodsTypeInfo(@RequestAttribute GoodsTypeSelectRequest request) {

        List<GoodsType> list = goodsTypeService.getAllChild(request.getCId());

        List<GoodsTypeSelectResponse> responseList = ConvertUtils.list(list, type -> GoodsTypeSelectResponse.builder()
                .goodstypeId(type.getGoodstypeId())
                .name(type.getGroupName())
                .build());

        return ResultModel.success(responseList);
    }

    @ApiOperation(value = "修改分类是否展示")
    @PostMapping("/updateGoodsTypeIsShow")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<Integer> updateGoodsTypeIsShow(@RequestAttribute GoodsTypeSaveRequest request) {
        goodsTypeService.updateGoodsTypeIsShow(request.getGoodstypeId(), request.getIsShow());
        return ResultModel.success();
    }

    @ApiOperation(value = "添加/修改商品分类")
    @PostMapping("/addGoodsType")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<Integer> addGoodsType(@RequestAttribute GoodsTypeSaveRequest request) {
        Integer goodsTypeId = goodsTypeService.save(request.getCId()
                , request.getName()
                , request.getParentId()
                , request.getGoodstypeId()
                , request.getIsShow()
                , null
        );
        return ResultModel.success(goodsTypeId);
    }

    @PostMapping("/delGoodsType")
    @ApiOperation(value = "删除商品分类")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel delGoodsType(@RequestAttribute GoodsTypeDelRequest request) {

        goodsTypeFeign.delete(com.jmp.base.dto.GoodsTypeDeleteRequest.builder().goodsTypeId(request.getGoodstypeId()).build());

        return ResultModel.success();
    }

    @PostMapping("/moveGoodsType")
    @ApiOperation(value = "上移/下移商品分类")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel moveGoodsType(@RequestAttribute GoodsTypeMoveRequest request) {

        goodsTypeService.updateSort(request.getGoodstypeId(), request.getType(), request.getCId().intValue());

        return ResultModel.success();
    }

    @PostMapping("/getGoodsInfo")
    @ApiOperation(value = "查询商品信息")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<List<GoodsInfoResponse>> getGoodsInfo(@RequestAttribute GoodsInfoRequest request) {
        AssertUtil.nonNull(request, ResultEnum.PARAM_CHECK);

        Goods goodsModel = goodsBaseService.get(request.getGoodsId());
        AssertUtil.nonNull(goodsModel, "商品不存在");
        AssertUtil.isTrue(goodsModel.getIsDel() == 0, "商品已下架");

        GoodsType goodsType = goodsTypeService.get(goodsModel.getGoodstypeId());

        List<String> photos = goodsPhotoService.getListPath(request.getGoodsId());
        String photosArr = StringUtils.join(photos, OneConstant.arraySymbol);

        GoodSpecModel specModel = new GoodSpecModel();
        specModel.setGoodsId(request.getGoodsId());
        specModel.setIsDel(0);
        List<GoodSpecModel> specModelList = goodSpecMapperExt.getSpec(specModel);
        List<GoodsInfoResponse.Spec> goodSpecModelList = ConvertUtils.list(specModelList, goodSpecModel -> GoodsInfoResponse.Spec.builder()
                .specId(goodSpecModel.getSpecId())
                .specName(goodSpecModel.getSpecName())
                .goodSpecModelList(ConvertUtils.list(goodSpecModel.getGoodSpecModelList(), spec -> GoodsInfoResponse.Spec.builder()
                        .specId(spec.getSpecId())
                        .specName(StringUtils.isNoneBlank(spec.getSpecAttribute()) ? spec.getSpecAttribute() : spec.getSpecName())
                        .specAttribute(StringUtils.isNoneBlank(spec.getSpecAttribute()) ? spec.getSpecAttribute() : spec.getSpecName())
                        .specNum(spec.getSpecNum())
                        .price(MoneyUtil.getMoney(spec.getPrice()))
                        .priceRemark(spec.getPriceRemark() == null ? null : BigDecimal.valueOf(spec.getPriceRemark()))
                        .build()))
                .build());

        GoodsInfoResponse goodsInfoResponse = GoodsInfoResponse.builder()
                .companyId(goodsModel.getCompanyId())
                .goodsName(goodsModel.getGoodsName())
                .goodstypeId(goodsModel.getGoodstypeId())
                .goodsTypeName(goodsType.getName())
                .goodsDetails(goodsModel.getGoodsDetails())
                .ispayment(goodsModel.getIsPayment())
                .goodPhoto(photosArr)
                .goodSpecModelList(goodSpecModelList)
                .showPrice(goodsModel.getShowPrice())
                .fromApp(goodsModel.getFromApp())
                .wholesaleInfo(goodsModel.getWholesaleInfo())
                .build();

        List<GoodsInfoResponse> responseList = Lists.newArrayList(goodsInfoResponse);
        return ResultModel.success(responseList);
    }

    @ApiOperation(value = "添加商品信息")
    @PostMapping("/addGoodsInfo")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel save(@RequestAttribute GoodsSaveRequest request) {
        final Integer userCompanyId = RequestContextHolder.getRequestContext().getUser().getCompanyId();

        com.jmp.base.dto.GoodsSaveRequest saveRequest = com.jmp.base.dto.GoodsSaveRequest.builder()
                .goodsId(request.getGoodsId())
                .goodsName(request.getGoodsName())
                .goodstypeId(request.getGoodstypeId())
                .goodsDetails(request.getGoodsDetails())
                .isPayment(request.getIspayment())
                .showPrice(request.getShowPrice())
                .coverImg(request.getCoverImg())
                .videoUrl(request.getVideoUrl())
                .goodPhoto(request.getGoodPhoto())
                .companyId(userCompanyId)
                .fromApp(Objects.isNull(request.getGoodsId()) ? 1 : null)
                .specList(request.getGoodSpecRequestList())
                .build();
        return goodsFeign.save(saveRequest);
    }

    @PostMapping("/addGoodSpecInfo")
    @ApiOperation(value = "添加商品规格信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "specName", value = "类型名称", required = true, paramType = "String"),
            @ApiImplicitParam(name = "specAttribute", value = "属性名", required = true, paramType = "String"),
            @ApiImplicitParam(name = "specNum", value = "库存", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "price", value = "价格(分)", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "parentId", value = "父级id（如果是类型的第一个属性就给0，如果不是就给第一个属性的specId）", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel addGoodSpecInfo(@RequestAttribute GoodSpecRequest request) {

        return crmFegin.addGoodSpecInfo(request);
    }

    @ApiOperation(value = "转移产品")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "goodsId", value = "商品ID", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "goodstypeId", value = "商品类型ID", required = true, paramType = "Integer"),
    })
    @PostMapping("/transferGoods")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel transferGoods(@RequestAttribute GoodsRequest request) {

        return crmFegin.transferGoods(request);
    }

    @ApiOperation(value = "删除商品信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "goodsId", value = "商品id", required = true, paramType = "Integer"),
    })
    @PostMapping("/delGoodsInfo")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel delGoodsInfo(@RequestAttribute GoodsRequest request) {

        return crmFegin.delGoodsInfo(request);
    }

    @PostMapping("/delGoodSpecInfo")
    @ApiOperation(value = "删除商品规格信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "specId", value = "商品分类id", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel delGoodSpecInfo(@RequestAttribute GoodSpecRequest request) {

        return crmFegin.delGoodSpecInfo(request);
    }

    @PostMapping("/card")
    @ApiOperation(value = "商品分享")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<GoodsCardResponse> cardUrl(@RequestAttribute GoodsCardRequest request) {
        TemplateGet2Request getRequest = TemplateGet2Request.builder()
                .templateType(TemplateApi.Type.ID_CRM_APP_GOODS)
                .cardId(request.getMyCardId())
                .goodsId(request.getGoodsId())
                .build();
        ResultModel<TemplateGetResponse> getResponseResultModel = templateFeign.get2(getRequest);
        AssertUtil.isTrue(getResponseResultModel);
        String cardUrl = getResponseResultModel.getData().getImageUrl();

        AccountCompanyIdRequest accountCompanyIdRequest = AccountCompanyIdRequest.builder()
                .companyId(request.getCId())
                .loginEnum(LoginEnum.USER)
                .build();
        ResultModel<AccountResponse> accountResponseResultModel = accountFeign.getCompanyIdDefaultIfNull(accountCompanyIdRequest);
        String wechatId = accountResponseResultModel.isSuccess() ? accountResponseResultModel.getData().getWechatId() : null;

        GoodsCardResponse response = GoodsCardResponse.builder()
                .cardId(request.getMyCardId())
                .cardUrl(cardUrl)
                .wechatId(wechatId)
                .oneWechat(companyBaseService.isOneWechat(request.getCId()))
                .build();
        return ResultModel.success(response);
    }

    @PostMapping("/main/push")
    @ApiOperation(value = "主推/取消主推")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel mainPush(@RequestAttribute com.jmp.api.dto.GoodsMainPushRequest request) {
        ResultModel resultModel = goodsFeign.mainPush(GoodsMainPushRequest.builder()
                .goodsId(request.getGoodsId())
                .mainPush(BooleanUtils.toBoolean(request.getMainPush()))
                .build());
        AssertUtil.isTrue(resultModel);
        return ResultModel.success();
    }
}
